<?php
/**
 * Base class for DB-Access, please implenent the following member variables
 * - $dbTable
 * - $rowClassType
 * 
 * @author michi
 *
 */
class DBList implements Iterator {
	
	protected $dbTable = "somewhat";
	protected $rowClassType = "YourDBListItemType";
	
	protected $parentItem;
	
	/**
	 * Internal storage for the Items
	 *
	 * @var DBListItem
	 */
	protected $items;
	protected $it=0;

	public function getDbTable() { return $this->dbTable; }
	
	function __construct(DBListItem $parentItem=null) {
		$this->parentItem = $parentItem;
	}
	
	function __call($name, $args) {
		
		if(strtolower(substr($name, 0, 5))==strtolower("GetBy")) {
			$field = substr($name, 5);

			$sqlA = $this->getSqlSelectQuery();
			$sqlA["WHERE"] = "$field = '" . mysql_real_escape_string($args[0]) . "'";
			
			$sql = $this->generateSqlQuery($sqlA);
			
			//echo $sql."<br>";
			return $this->execute($sql);
			//create generic statement for that
		}
		elseif(strtolower(substr($name, 0, 11))==strtolower("GetAllItems") && strtolower(substr($name,-7))==strtolower("Ordered")) {
			
			//Try to load items ordered by the column specified
			$column = substr($name, 11, -7);
			
			$sql = "SELECT * FROM " . $this->dbTable . " WHERE 1 ORDER BY `$column`";
			return $this->execute($sql);
			
		}
		else {
			user_error("Method '$name' not implemented");
			debug_print_backtrace();
			return null;
		}
		
	}
	
	function getSqlSelectQuery() {
		
		//Determine Coumns from SQL-Table
		$res = MySQLConnection::getInstance()->Query("SHOW COLUMNS FROM $this->dbTable");

		$availableFields = array();
		
		while(($row = mysql_fetch_array($res))==true) {
			$availableFields[$row[0]] = $row;
		}
		
		$addFields = "";
		$addJoin = "";
		if(array_key_exists("createUser", $availableFields)) {
			$addFields.=", lnkCreateUser.realName AS createUserName";
			$addJoin.="LEFT JOIN tblSecurityUser AS lnkCreateUser ON lnkCreateUser.pkSecurityUser = t.createUser ";
		}
		if(array_key_exists("changeUser", $availableFields)) {
			$addFields.=", lnkChangeUser.realName AS changeUserName";
			$addJoin.="LEFT JOIN tblSecurityUser AS lnkChangeUser ON lnkChangeUser.pkSecurityUser = t.changeUser ";
		}
		
		if(array_key_exists("sortId", $availableFields)) { $SortId = "sortId"; }
		elseif(array_key_exists("position", $availableFields)) { $SortId = "position"; }
		elseif(array_key_exists("name", $availableFields)) { $SortId = "name ASC"; }
		elseif(array_key_exists("lastname", $availableFields)) { $SortId = "t.lastname ASC"; }
		
		
		$retVal["SELECT"] =  "t.*" . $addFields . "\n";
		$retVal["FROM"] =    $this->dbTable . " AS t \n";
		$retVal["FROM"].=    $addJoin . ($addJoin?"\n":"");
		if(isset($SortId)) { $retVal["ORDER"] = $SortId; }
		$retVal["WHERE"] = "1=1";
		return $retVal;
	}
	
	function generateSqlQuery($sqlStatementArray) {
		
		$sql = "SELECT " . $sqlStatementArray["SELECT"];
		$sql.= "FROM " . $sqlStatementArray["FROM"];
		$sql.= "WHERE " . $sqlStatementArray["WHERE"];
		if(isset($sqlStatementArray["ORDER"])) { $sql.= " ORDER BY " . $sqlStatementArray["ORDER"]; }
		
		return $sql;
	}
	
	/**
	 * Get All Items from a Table
	 *
	 * @return DBList
	 */
	
	function GetAllItems() {
		
		$sql = "SELECT * FROM " . $this->dbTable . " WHERE 1";
		
		
		//Chech if there is a Sortid
		$column = MySQLConnection::getInstance()->quickQuery("SHOW COLUMNS FROM $this->dbTable WHERE Field = 'sortId'");
		
		if(is_array($column)) {
			$sql.= " ORDER BY sortId";
		}

		//echo $sql."<br>";
		return $this->execute($sql);
	}
	
	/*
	 * Iterator Implementation
	 * -----------------------
	 */
	
	public function rewind() {
          $this->it = 0;
      }
  
      public function key() {
          return $this->it;
     }
 
     public function current() {
         
     	if($this->it >= 0 && $this->it < count($this->items)) {
     		return $this->items[$this->it];
     	}
     	else {
     		throw new Exception("Invalid key given");
     	}
      }
 
     public function valid() {
         return $this->it < count($this->items);
     }
 
     public function next() {
         ++$this->it;
     }
	 /**
	  * 
	  * @param $index
	  * @return DBListItem
	  */
     public function At($index) {
     	if(isset($this->items[$index])) {
     		return $this->items[$index];
     	}
     	else {
     		user_error("Index $index is out of bounds. Calling from");
     		debug_print_backtrace();
     	}
     }
     
     public function count() {
     	return $this->items ? count($this->items): null;
     }
     
	/**
	 * Executes a Query on the given Table
	 *
	 * @param strinng $query
	 * @param array $variables
	 * @return array
	 */		
	protected function execute($query, $variables="") {
		
		$conn = MySQLConnection::getInstance();
		$this->items = array();
		
		
		$res = $conn->query($query, $variables);
		
		if($res) {
			$first = null;
			$row = null;

			while(($data = @mysql_fetch_array($res))) {

				$row = new $this->rowClassType($data, $this);
				$row->setTable($this);
				
				if(!$first) { $first = $row; }
				//$row->fetchData($data);
				
				$row->setIsFirst(false);
				$row->setIsLast(false);
				
				array_push($this->items, $row);	
			}
			
			if($row) {
				$first->setIsFirst(true);
				$row->setIsLast(true);
			}
		}
		else {
			//echo "query failed-";
			Logger::logEvent("QueryFailed", __FILE__, __CLASS__, __FUNCTION__, __LINE__, array("query"=>$conn->getLastQuery(), "classType"=>$this->rowClassType));
		}
		
		return $this;		
	}
	
	protected function setParentItem(DBListItem $item) {
		$this->parentItem = $item;
	}
	
	public function getParentItem() {
		return $this->parentItem;
	}
	
}



/*
function get_called_class ($i_level = 1) 
{ 
    $a_debug = debug_backtrace(); 
    $a_called = array(); 
    $a_called_function = $a_debug[$i_level]['function']; 
    for ($i = 1, $n = sizeof($a_debug); $i < $n; $i++) 
    { 
        if (in_array($a_debug[$i]['function'], array('eval')) || 
            strpos($a_debug[$i]['function'], 'eval()') !== false) 
            continue; 
        if (in_array($a_debug[$i]['function'], array('__call', '__callStatic'))) 
            $a_called_function = $a_debug[$i]['args'][0]; 
        if ($a_debug[$i]['function'] == $a_called_function) 
            $a_called = $a_debug[$i]; 
    } 
    if (isset($a_called['object']) && isset($a_called['class'])) 
        return (string)$a_called['class']; 
    $i_line = (int)$a_called['line'] - 1; 
    $a_lines = explode("\n", file_get_contents($a_called['file'])); 
    preg_match("#([a-zA-Z0-9_]+){$a_called['type']} 
                {$a_called['function']}( )*\(#", $a_lines[$i_line], $a_match); 
    unset($a_debug, $a_called, $a_called_function, $i_line, $a_lines); 
    if (sizeof($a_match) > 0) 
        $s_class = (string)trim($a_match[1]); 
    else 
        $s_class = (string)$a_called['class']; 
    if ($s_class == 'self') 
        return get_called_class($i_level + 2); 
    return $s_class; 
}
*/
?>